import mongoose, { Schema, Document } from 'mongoose';

/**
 * 组织接口定义
 */
export interface IOrganization extends Document {
  name: string;
  slug: string; // URL友好的唯一标识
  description?: string;
  logo?: string;
  website?: string;
  settings: {
    maxMembers: number;
    allowPublicJoin: boolean;
    requireApproval: boolean;
  };
  billing?: {
    plan: 'free' | 'pro' | 'enterprise';
    maxUsers: number;
    maxTeams: number;
    expiresAt?: Date;
  };
  owner: mongoose.Types.ObjectId; // 组织所有者
  admins: mongoose.Types.ObjectId[]; // 组织管理员
  members: mongoose.Types.ObjectId[]; // 组织成员
  teams: mongoose.Types.ObjectId[]; // 组织下的团队
  isActive: boolean;
  metadata?: {
    industry?: string;
    size?: string;
    location?: string;
  };
  createdAt: Date;
  updatedAt: Date;
}

/**
 * 组织 Schema
 */
const OrganizationSchema = new Schema<IOrganization>(
  {
    name: {
      type: String,
      required: [true, 'Organization name is required'],
      trim: true,
      minlength: [2, 'Organization name must be at least 2 characters'],
      maxlength: [100, 'Organization name cannot exceed 100 characters']
    },
    slug: {
      type: String,
      required: true,
      unique: true,
      lowercase: true,
      trim: true,
      match: [/^[a-z0-9-]+$/, 'Slug can only contain lowercase letters, numbers and hyphens']
    },
    description: {
      type: String,
      maxlength: [500, 'Description cannot exceed 500 characters']
    },
    logo: {
      type: String,
      default: null
    },
    website: {
      type: String,
      match: [/^https?:\/\/.+/, 'Please provide a valid URL']
    },
    settings: {
      maxMembers: {
        type: Number,
        default: 100
      },
      allowPublicJoin: {
        type: Boolean,
        default: false
      },
      requireApproval: {
        type: Boolean,
        default: true
      }
    },
    billing: {
      plan: {
        type: String,
        enum: ['free', 'pro', 'enterprise'],
        default: 'free'
      },
      maxUsers: {
        type: Number,
        default: 10
      },
      maxTeams: {
        type: Number,
        default: 3
      },
      expiresAt: {
        type: Date
      }
    },
    owner: {
      type: Schema.Types.ObjectId,
      ref: 'User',
      required: true
    },
    admins: [{
      type: Schema.Types.ObjectId,
      ref: 'User'
    }],
    members: [{
      type: Schema.Types.ObjectId,
      ref: 'User'
    }],
    teams: [{
      type: Schema.Types.ObjectId,
      ref: 'Team'
    }],
    isActive: {
      type: Boolean,
      default: true
    },
    metadata: {
      industry: String,
      size: {
        type: String,
        enum: ['1-10', '11-50', '51-200', '201-500', '501-1000', '1000+']
      },
      location: String
    }
  },
  {
    timestamps: true,
    toJSON: { virtuals: true },
    toObject: { virtuals: true }
  }
);

// 索引
OrganizationSchema.index({ slug: 1 });
OrganizationSchema.index({ owner: 1 });
OrganizationSchema.index({ members: 1 });
OrganizationSchema.index({ isActive: 1 });

// 虚拟字段：成员数量
OrganizationSchema.virtual('memberCount').get(function(this: IOrganization) {
  return this.members.length;
});

// 虚拟字段：团队数量
OrganizationSchema.virtual('teamCount').get(function(this: IOrganization) {
  return this.teams.length;
});

// 实例方法：检查用户是否是组织成员
OrganizationSchema.methods.isMember = function(userId: string): boolean {
  return this.members.some((id: mongoose.Types.ObjectId) => id.toString() === userId.toString());
};

// 实例方法：检查用户是否是管理员
OrganizationSchema.methods.isAdmin = function(userId: string): boolean {
  return this.admins.some((id: mongoose.Types.ObjectId) => id.toString() === userId.toString()) ||
         this.owner.toString() === userId.toString();
};

// 实例方法：检查用户是否是所有者
OrganizationSchema.methods.isOwner = function(userId: string): boolean {
  return this.owner.toString() === userId.toString();
};

// 静态方法：根据 slug 查找组织
OrganizationSchema.statics.findBySlug = function(slug: string) {
  return this.findOne({ slug, isActive: true });
};

const Organization = mongoose.model<IOrganization>('Organization', OrganizationSchema);

export default Organization;
